﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Frogism.Core {
  public class NetWorthItem : ObjectIdBase, INetWorth {
      public static NetWorthItem CreateRetirement(IEnumerable<IAccount> accounts)
      {
      return NetWorthItem.CreateRetirement(accounts, DateTime.Now);
    }
      public static NetWorthItem CreateInvestment(IEnumerable<IAccount> accounts)
      {
      return NetWorthItem.CreateInvestment(accounts, DateTime.Now);
    }
      public static NetWorthItem CreateMortgage(IEnumerable<IAccount> accounts)
      {
          return NetWorthItem.CreateMortgage(accounts, DateTime.Now);
      }
      public static NetWorthItem CreateCash(IEnumerable<IAccount> accounts)
      {
      return NetWorthItem.CreateCash(accounts, DateTime.Now);
    }
      public static NetWorthItem CreateDebit(IEnumerable<IAccount> accounts)
      {
      return NetWorthItem.CreateDebit(accounts, DateTime.Now);
    }
      public static NetWorthItem CreateLiquid(IEnumerable<IAccount> accounts)
      {
      return NetWorthItem.CreateLiquid(accounts, DateTime.Now);
    }
      public static NetWorthItem CreateNetWorth(IEnumerable<IAccount> accounts)
      {
      return NetWorthItem.CreateNetWorth(accounts, DateTime.Now);
    }
      public static NetWorthItem CreateRetirement(IEnumerable<IAccount> accounts, DateTime AsOfDate)
      {
      return new NetWorthItem("Retirement", accounts, new RetirementFilter());
    }
      public static NetWorthItem CreateInvestment(IEnumerable<IAccount> accounts, DateTime AsOfDate)
      {
      return new NetWorthItem("Investment", accounts, new InvestmentFilter());
    }
      public static NetWorthItem CreateMortgage(IEnumerable<IAccount> accounts, DateTime AsOfDate)
      {
          return new NetWorthItem("Mortgage", accounts, new MortgageFilter());
      }
      public static NetWorthItem CreateCash(IEnumerable<IAccount> accounts, DateTime AsOfDate)
      {
      return new NetWorthItem("Cash", accounts, new CashFilter());
    }
      public static NetWorthItem CreateDebit(IEnumerable<IAccount> accounts, DateTime AsOfDate)
      {
      return new NetWorthItem("Debit", accounts, new DebitFilter());
    }
      public static NetWorthItem CreateLiquid(IEnumerable<IAccount> accounts, DateTime AsOfDate)
      {
      return new NetWorthItem("Liquid", accounts, new LiquidFilter());
    }
      public static NetWorthItem CreateNetWorth(IEnumerable<IAccount> accounts, DateTime AsOfDate)
      {
      return new NetWorthItem("NetWorth", accounts, new AntiFilter());
    }

    private INetWorthFilter Filter { get; set; }
    private IEnumerable<IAccount> _Accounts;
    protected IEnumerable<IAccount> Accounts { get { return _Accounts; } }
    private NetWorthItem(string label, IEnumerable<IAccount> accounts, INetWorthFilter filter)
    {
      Filter = filter;
      _Label = label;
      _Accounts = accounts.Where(a => Filter.ValidAccount(a));
    }
    #region INetWorth Members
    private string _Label;
    public string Label {
      get { return _Label; }
    }
    
    public decimal Change {
      get { return (Balance - PreviousMonth); }
    }

    #endregion
 
    public decimal PreviousMonth {
      get {

        return Accounts.Sum(a => a.LastMonth);
      }
    }

    public decimal Balance {
      get { return Accounts.Sum(a => a.Balance); }
    }

    public decimal Goal {
      get { return Accounts.Sum(a => a.NextGoalValue); }
    }

    public decimal Start {
      get { return Accounts.Sum(a => a.Start); }
    }

    public decimal Progress {
      get { return Balance - Start; }
    }

    public decimal YearStart {
      get { return Accounts.Sum(a => a.YearStart); }
    }


    public decimal ToGo {
      get { return Goal - Balance; }
    }
    public double YearsTillRetirement
    {
        get
        {
            DateTime birthdate = new DateTime(1978, 8, 14);
            DateTime retiredate = birthdate.AddYears(65);
            double YearsTillThen = retiredate.Subtract(DateTime.Now).TotalDays / 365;
            return YearsTillThen;
        }
    }
    public int When65
    {
        get { return Convert.ToInt32(Math.Round((double)Balance * Math.Pow(1.08d, YearsTillRetirement), 0)); }
    }


   
  }
}
